package com.parsifal.client.socket;

import android.util.Log;

import com.parsifal.client.callback.SocketStateCallback;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by yangming on 17-3-31.
 */
public class Client {

    private static final String TAG = Client.class.getSimpleName();

    private String mIP = null;

    private int mPort = 0;

    private Socket mSocket = null;

    private boolean mClientRun = false;

    private SocketStateCallback mSocketStateCallback = null;

    private ExecutorService mThreadPool = null;

    public String getIP() {
        return mIP;
    }

    public void setIP(String ip) {
        this.mIP = ip;
    }

    public int getPort() {
        return mPort;
    }

    public void setPort(int port) {
        this.mPort = port;
    }

    public void connect() {
        if (!mClientRun) {
            mThreadPool = Executors.newFixedThreadPool(2);
            Runnable clientThread = new Runnable() {
                @Override
                public void run() {
                    try {
                        Log.e(TAG, "mIP " + mIP);
                        Log.e(TAG, "mPort " + mPort);
                        mSocket = new Socket(mIP, mPort);
                        if (null != mSocketStateCallback) {
                            mSocketStateCallback.onConnected();
                        }
                        mClientRun = true;
                        while (mClientRun) {
                            InputStream inputStream = mSocket.getInputStream();
                            byte[] buffer = new byte[1024];
                            BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
                            int length = bufferedInputStream.read(buffer);
                            if (0 < length) {
                                String serverMsg = new String(buffer, 0, length);
                                if (null != mSocketStateCallback) {
                                    mSocketStateCallback.onReceive(serverMsg);
                                }
                            }
                        }
                    } catch (Exception e) {
                        try {
                            mSocket.close();
                            mClientRun = false;
                            if (null != mSocketStateCallback) {
                                mSocketStateCallback.onDisconnected();
                            }
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                        e.printStackTrace();
                    }
                }
            };
            mThreadPool.execute(clientThread);
            Log.i(TAG, "客户端 ON");
        }
    }

    public void send(final String clientMsg) {
        try {
            mThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        OutputStream outputStream = mSocket.getOutputStream();
                        outputStream.write(clientMsg.getBytes());
                        outputStream.flush();
                        if (null != mSocketStateCallback) {
                            mSocketStateCallback.onSend(clientMsg);
                        }
                    } catch (Exception e) {
                        try {
                            mSocket.close();
                        } catch (Exception e1) {
                            e1.printStackTrace();
                        }
                        e.printStackTrace();
                    }
                }
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setSocketStateCallback(SocketStateCallback callback) {
        this.mSocketStateCallback = callback;
    }

    public void stopClient() {
        mClientRun = false;
        if (null != mSocket) {
            try {
                mSocket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (null != mThreadPool) {
            mThreadPool.shutdownNow();
        }
    }
}
